Adding --limit usage suggestion on search results (#2402)
authorJesús Espino <jespinog@gmail.com>
Mon, 7 Mar 2016 08:19:40 +0000 (09:19 +0100)
committerJesús Espino <jespinog@gmail.com>
Tue, 8 Mar 2016 08:31:26 +0000 (09:31 +0100)
Cargo.lock
src/bin/cargo.rs
src/cargo/ops/registry.rs
src/crates-io/Cargo.toml
src/crates-io/lib.rs

index 3c3b25d2b6b0617de9b77fd2e62a37da122213d5..705299f152d759114bcd50db3df884fd25e95e9d 100644 (file)
@@ -73,6 +73,7 @@ version = "0.1.0"
 dependencies = [
  "curl 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
+ "url 0.2.38 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
index 0e007132397da2015755af822024988f7c0e76db..f01efb2bc0c42692b3f97a5771b4ae1e5d87cac4 100644 (file)
@@ -1,4 +1,5 @@
 extern crate cargo;
+extern crate url;
 extern crate env_logger;
 extern crate git2_curl;
 extern crate rustc_serialize;
index da2d800220e6c5ea4620be493ddef0235db65fd4..a02b80a6ba27c01f9787b09335feae7942e3d403 100644 (file)
@@ -10,6 +10,8 @@ use git2;
 use registry::{Registry, NewCrate, NewCrateDependency};
 use term::color::BLACK;
 
+use url::percent_encoding::{percent_encode, QUERY_ENCODE_SET};
+
 use core::source::Source;
 use core::{Package, SourceId};
 use core::dependency::Kind;
@@ -353,7 +355,7 @@ pub fn search(query: &str,
     }
 
     let (mut registry, _) = try!(registry(config, None, index));
-    let crates = try!(registry.search(query, limit).map_err(|e| {
+    let (crates, total_crates) = try!(registry.search(query, limit).map_err(|e| {
         human(format!("failed to retrieve search results from the registry: {}", e))
     }));
 
@@ -381,5 +383,23 @@ pub fn search(query: &str,
         try!(config.shell().say(line, BLACK));
     }
 
+    let search_max_limit = 100;
+    if total_crates > limit as u32 && limit < search_max_limit {
+        try!(config.shell().say(
+            format!("... and {} crates more (use --limit N to see more)",
+                    total_crates - limit as u32),
+            BLACK)
+        );
+    } else if total_crates > limit as u32 && limit >= search_max_limit {
+        try!(config.shell().say(
+            format!(
+                "... and {} crates more (go to http://crates.io/search?q={} to see more)",
+                total_crates - limit as u32,
+                percent_encode(query.as_bytes(), QUERY_ENCODE_SET)
+            ),
+            BLACK)
+        );
+    }
+
     Ok(())
 }
index 70068ec5bf23248be3ed0cd1e90f25870b7a43e0..298d4707a544cacc1346e885af940ea6817355b9 100644 (file)
@@ -14,4 +14,5 @@ path = "lib.rs"
 
 [dependencies]
 curl = "0.2"
+url = "0.2"
 rustc-serialize = "0.3"
index 0586c76f2fcd15986f521094237240ebbe01817b..4e49dacd9f2557b80bc7befdf9a52659a1793135 100644 (file)
@@ -1,4 +1,5 @@
 extern crate curl;
+extern crate url;
 extern crate rustc_serialize;
 
 use std::collections::HashMap;
@@ -14,6 +15,8 @@ use curl::http::handle::Method::{Put, Get, Delete};
 use curl::http::handle::{Method, Request};
 use rustc_serialize::json;
 
+use url::percent_encoding::{percent_encode, QUERY_ENCODE_SET};
+
 pub struct Registry {
     host: String,
     token: Option<String>,
@@ -88,7 +91,8 @@ pub struct User {
 #[derive(RustcDecodable)] struct ApiError { detail: String }
 #[derive(RustcEncodable)] struct OwnersReq<'a> { users: &'a [&'a str] }
 #[derive(RustcDecodable)] struct Users { users: Vec<User> }
-#[derive(RustcDecodable)] struct Crates { crates: Vec<Crate> }
+#[derive(RustcDecodable)] struct TotalCrates { total: u32 }
+#[derive(RustcDecodable)] struct Crates { crates: Vec<Crate>, meta: TotalCrates }
 
 impl Registry {
     pub fn new(host: String, token: Option<String>) -> Registry {
@@ -170,11 +174,15 @@ impl Registry {
         Ok(())
     }
 
-    pub fn search(&mut self, query: &str, limit: u8) -> Result<Vec<Crate>> {
-        let body = try!(self.req(format!("/crates?q={}&per_page={}", query, limit), None, Get,
-                                 Auth::Unauthorized));
+    pub fn search(&mut self, query: &str, limit: u8) -> Result<(Vec<Crate>, u32)> {
+        let formated_query = percent_encode(query.as_bytes(), QUERY_ENCODE_SET);
+        let body = try!(self.req(
+            format!("/crates?q={}&per_page={}", formated_query, limit),
+            None, Get, Auth::Unauthorized
+        ));
 
-        Ok(json::decode::<Crates>(&body).unwrap().crates)
+        let crates = json::decode::<Crates>(&body).unwrap();
+        Ok((crates.crates, crates.meta.total))
     }
 
     pub fn yank(&mut self, krate: &str, version: &str) -> Result<()> {